package control
{
	import events.IEvent;
	
	import flash.events.Event;
	
	import model.ModelLocator;
	
	import mx.collections.ArrayCollection;
	import mx.collections.IViewCursor;
	import mx.collections.Sort;
	import mx.collections.SortField;
	import mx.controls.Alert;
	import mx.managers.CursorManager;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;
	
	import vo.Type;
	import vo.Ware;
	
	public class Control
	{
		internal var theModel:ModelLocator = ModelLocator.GetInstance();
				
		public function Control():void
		{
		}

		private function SendHttpService( url:String, param:Object = null, Callback:Function = null ):void
		{
			var httpServiceObj:HTTPService = new HTTPService();
			httpServiceObj.resultFormat = "text";
			httpServiceObj.method = "POST";
			httpServiceObj.url = url;
			httpServiceObj.addEventListener( FaultEvent.FAULT, function( evt:FaultEvent ):void
							{
								Alert.show( evt.message.toString() );
							} );
			httpServiceObj.addEventListener( ResultEvent.RESULT, function(evt:ResultEvent ):void
							{
								CursorManager.removeBusyCursor();
								var resultStringArr:Array = evt.result.toString().split( "</response>" );
								var responseXml:XML = XML( resultStringArr[0] + "</response>" );
								if( Callback != null )
								{
									Callback.call(null,responseXml);	
								}
							}  );
			httpServiceObj.send(param);
			CursorManager.setBusyCursor();
		}
		private function GetParam():Object
		{
			var obj:Object = new Object();
			obj.curUserId = theModel.curUser.id;
			obj.curUserName = theModel.curUser.name;
			obj.curUserPermission = theModel.curUser.permission;
			return obj;
		}
		private function IsFalseResult( responseXml:XML, func:Function = null ):Boolean
		{
			if( responseXml.result == "false" )
			{
				if( func == null )
					Alert.show( "操作失败\n" + responseXml.message );
				else
					func.apply(this);
				return true;
			}
			return false;
		}
		public function Regist( id:String, permission:int, pass:String, email:String ):void
		{
			var param:Object = GetParam();
			param.operation = "ADDUSER"; 
			param.userId = id;
			param.permission = permission;
			param.pass = pass;
			param.email = email;
			SendHttpService( "data/operation.php?random=" + Math.random(), param,RegistHandler);
		}
		internal function RegistHandler( responseXml:XML ):void
		{
			if( !IsFalseResult(responseXml))
			{
				Alert.show( "添加用户成功!" );
			}
			this.GetUserList();
		}
		public function ResetPass( userName:String, pass:String = "888888"):void
		{
			var param:Object = GetParam();
			param.operation = "RESETPASS";
			param.userName = userName;
			param.pass = pass;
			SendHttpService( "data/operation.php?random=" + Math.random(), param,ResetPassHandler);
		}
		internal function ResetPassHandler(responseXml:XML ):void
		{
			if( responseXml.result == "true" )
			{
				Alert.show( "用户密码已经重新设置" );
			}
			this.GetUserList();
		}
		public function DeleteUser( userObj:Object ):void
		{
			var param:Object = GetParam();
			param.operation = "DELETEUSER";
			param.userName = userObj.name;
			SendHttpService( "data/operation.php?random=" + Math.random(), param,DeleteUserHandler);
		}
		internal function DeleteUserHandler(responseXml:XML):void
		{
			if( responseXml.result == "true" )
			{
				Alert.show( "用户已删除." );
			}
			this.GetUserList();
		}
		public function Login( id:String, pass:String ):void
		{
			var param:Object = GetParam();
			param.operation = "LOGIN";
			param.userId = id;
			param.pass = pass;
			SendHttpService( "data/operation.php?random=" + Math.random(), param,LoginHandler);
		}
		internal function LoginHandler( responseXml:XML):void
		{
			trace( responseXml );
			if( int(responseXml.PERMISSION) > 0 )
			{
				theModel.curUser.name = responseXml.NAME;
				theModel.curUser.id= responseXml.ID;
				theModel.curUser.pass = responseXml.PASS;
				theModel.curUser.permission = responseXml.PERMISSION;
				theModel.isLogin = true;
				// 发布登陆成功消息
				theModel.dispatchEvent( new Event( IEvent.LOGIN_OK ) );
				GetType( null );
				GetWareList(null);
				GetClientList(null);
			}
			else 
			{
				//Alert.show(responseXml.NAME);
				//Alert.show(responseXml.PASS);
				theModel.isLogin = false;
				theModel.dispatchEvent( new Event( IEvent.LOGIN_FAILED ) );
			}	
		}
		public function GetWareList(evt:Event):void
		{
			var param:Object = GetParam();
			param.operation = "GETWARELIST";
			SendHttpService("data/operation.php?random=" + Math.random(),param,GetWareListHandler);
		}
		
		internal function GetWareListHandler( responseXml:XML ):void
		{
			theModel.wareList=new ArrayCollection();
			for( var i:String in responseXml.row )
			{
				var obj:Ware = new Ware();
				var node:XML = responseXml.row[i];
				obj.id = node.ID;
				obj.name = node.NAME;
				obj.unit = node.UNIT;
				for( var j:int = 0; j < theModel.typeList.length; j ++ )
				{
					if( theModel.typeList[j].id == int(node.TYPE) )
					{
						obj.typeName =  theModel.typeList[j].name;
						break;
					}
				}
				obj.type = int(node.TYPE);
				obj.remainwz = node.REMAINWZ;
				obj.remainml = node.REMAINML;
				obj.remaingl = node.REMAINGL;
				obj.supply = node.SUPPLY;
				obj.misc = node.MISC;
				theModel.wareList.addItem( obj );
			}
			theModel.dispatchEvent( new Event( IEvent.GETWARELISTDONE ) );
		}
		public function GetTicketList( evt:Event, startDate:String="", endDate:String="",clientPhone:String="",clientName:String="" ):void
		{
			var param:Object = GetParam();
			param.startDate = startDate;
			param.endDate = endDate;
			param.clientPhone = clientPhone;
			param.clientName = clientName;
			param.operation = "GETTICKETLIST";
			SendHttpService("data/operation.php?random=" + Math.random(),param,GetTicketListHandler);
		}
		internal function GetTicketListHandler( responseXml:XML ):void
		{
			trace( responseXml );
			//httpService2.removeEventListener( ResultEvent.RESULT, GetTicketListHandler );
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			theModel.ticketList.removeAll();
			for( var i:String in responseXml.row )
			{
				//trace(node.title);
				var obj:Object = new Object();
				var node:XML = responseXml.row[i];
				obj.id = node.ID;
				obj.operation= node.OPERATION;
				obj.ticketDate = node.TICKETDATE;
				obj.realPay = node.REALPAY;
				obj.shouldPay = node.SHOULDPAY;
				obj.inputDate = node.INPUTDATE;
				obj.location = node.LOCATION;
				obj.misc = node.MISC;
				theModel.ticketList.addItem( obj );
			}
			theModel.dispatchEvent( new Event( IEvent.TICKETLISTCHANGED ) );
		}
		public function GetUserList():void
		{
			var param:Object = GetParam();
			param.operation = "GETUSERLIST";
			SendHttpService("data/operation.php?random=" + Math.random(),param,GetUserListHandler);
		}
		internal function GetUserListHandler(responseXml:XML):void
		{
			trace( responseXml );
			theModel.userList.removeAll();
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			for( var i:String in responseXml.row )
			{
				//trace(node.title);111
				var obj:Object = new Object();
				var node:XML = responseXml.row[i];
				obj.id = node.ID;
				obj.name = node.NAME;
				obj.regDate = node.REGDATE;
				obj.permission = node.PERMISSION;
				obj.misc = node.MISC;
				theModel.userList.addItem( obj );
			}
		}
		
		public function AddClient( name:String, company:String, type:String, phone1:String, phone2:String,
											phone3:String, address:String, misc:String ):void
		{
			var param:Object = GetParam();
			param.operation = "ADDCLIENT";
			param.name = name;
			param.company = company;
			param.type = type;
			param.phone1 = phone1;
			param.phone2 = phone2;
			param.phone3 = phone3;
			param.address = address;
			param.misc = misc;
			SendHttpService("data/operation.php?random=" + Math.random(),param,AddClientHandler);
		}
		internal function AddClientHandler( responseXml:XML ):void
		{
			if( responseXml.result == "false" )
			{
				Alert.show( responseXml.message,"号码已存在" );
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.CLIENTADDED ));
			}
		}
		public function GetClientList(evt:Event):void
		{
			var param:Object = GetParam();
			param.operation = "GETCLIENTLIST";
			SendHttpService("data/operation.php?random=" + Math.random(),param,GetClientListHandler);
		}
		internal function GetClientListHandler( responseXml:XML ):void
		{
			theModel.clientList.removeAll();
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			for( var i:String in responseXml.row )
			{
				//trace(node.title);
				var obj:Object = new Object();
				var node:XML = responseXml.row[i];
				obj.id = node.ID;
				obj.name = node.NAME;
				obj.company = node.COMPANY;
				obj.type = node.TYPE;
				obj.address = node.ADDRESS;
				obj.phone1 = node.PHONE1;
				obj.phone2 = node.PHONE2;
				obj.phone3 = node.PHONE3;
				obj.misc = node.MISC;
				theModel.clientList.addItem( obj );
			}
		}
		public function AddType( name:String, misc:String ):void
		{
			var param:Object = GetParam();
			param.operation = "ADDTYPE";
			param.typeName = name;
			param.typeMisc = misc;
			SendHttpService("data/operation.php?random=" + Math.random(),param,OnlyResultHandler);
		}
		// 没用到
		internal function AddTypeHandler( responseXml:XML ):void
		{
			//trace( evt.result);
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.ADDTYPEDONE ));
				theModel.dispatchEvent( new Event( IEvent.OPERATIONSUCCEED ));
			}
		}
		// 对insert, update, delete等不需要对返回结果进行处理的请求
		internal function OnlyResultHandler( responseXml:XML ):void
		{
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.TYPECHANGED ));
				theModel.dispatchEvent( new Event( IEvent.OPERATIONSUCCEED));
			}
		}
		public function GetType(evt:Event):void
		{
			var param:Object = GetParam();
			param.operation = "GETTYPE";
			SendHttpService("data/operation.php?random=" + Math.random(),param,GetTypeHandler);
		}
		internal function GetTypeHandler( responseXml:XML ):void
		{
			trace( responseXml );
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			var items:ArrayCollection = new ArrayCollection();
			for( var i:String in responseXml.row )
			{
				//trace(node.title);				
				var obj:Type = new Type();
				var node:XML = responseXml.row[i];
				obj.id = node.ID;
				obj.name = node.NAME;
				obj.misc = node.MISC;
				items.addItem( obj );
			}
			theModel.typeList.removeAll();
			theModel.typeList = items;
			theModel.dispatchEvent( new Event( IEvent.TYPEUPDATED ));
		}
		public function DeleteType( id:int ):void
		{
			var param:Object = GetParam();
			param.id = id;
			param.operation = "DELETETYPE";
			SendHttpService("data/operation.php?random=" + Math.random(),param,OnlyResultHandler);
		}
		public function EditType( id:int, name:String, misc:String):void
		{
			var param:Object = GetParam();
			param.id = id;
			param.name = name;
			param.misc = misc;
			param.operation = "EDITTYPE";
			SendHttpService("data/operation.php?random=" + Math.random(),param,OnlyResultHandler);
		}
		public function UpdateTypeCombo(evt:Event):void
		{
			theModel.typeCombo = new Array();
			theModel.typeCombo.push({label:"全部类别",data:null});
			for( var i:int = 0; i < theModel.typeList.length; i++)
			{
				theModel.typeCombo.push({label:theModel.typeList[i].name,data:theModel.typeList[i].id});
			}
		}
		public function AddWare( name:String, unit:String, typeId:String, 
								 storewz:int, storeml:int, storegl:int, supply:String, misc:String ):void
		{
			var param:Object = GetParam();
			param.name = name;
			param.unit = unit;
			param.typeId = typeId;
			param.storewz = storewz;
			param.storeml = storeml;
			param.storegl = storegl;
			param.supply = supply;
			param.misc = misc;
			param.operation = "ADDWARE";
			SendHttpService("data/operation.php?random=" + Math.random(),param,AddWareHandler);
		}
		internal function AddWareHandler( responseXml:XML ):void
		{
			trace(responseXml);
			//var responseXml:XML = GetResponseXml(evt.result.toString());
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.ADDWAREOK ));
			}
		}
		public function DeleteWare( id:int ):void
		{
			var param:Object = GetParam();
			param.id = id;
			param.operation = "DELETEWARE";
			SendHttpService("data/operation.php?random=" + Math.random(),param,DeleteWareHandler);
		}
		internal function DeleteWareHandler( responseXml:XML ):void
		{
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.DELETEWAREOK ));
			}
		}
		public function DeleteClient( id:int ):void
		{
			var param:Object = GetParam();
			param.id = id;
			param.operation = "DELETECLIENT";
			SendHttpService("data/operation.php?random=" + Math.random(),param,DeleteClientHandler);
		}
		internal function DeleteClientHandler( responseXml:XML ):void
		{
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.CLIENTDELETED ));
			}
		}
		public function EditClient( id:int, name:String, company:String, type:String, address:String, phone1:String,
									phone2:String, phone3:String, misc:String ):void
		{
			var param:Object = GetParam();
			param.id = id;
			param.name = name;
			param.company = company;
			param.type = type;
			param.address = address;
			param.phone1 = phone1;
			param.phone2 = phone2;
			param.phone3 = phone3;
			param.misc = misc;
			param.operation = "UPDATECLIENT";
			SendHttpService("data/operation.php?random=" + Math.random(),param,UpdateClientHandler);
		}
		internal function UpdateClientHandler( responseXml:XML ):void
		{
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.CLIENTUPDATED ));
			}
		}
		public function UpdateWare(id:String, name:String, unit:String, typeId:String, 
									storewz:String, storeml:String, storegl:String,
									supplier:String, misc:String):void
		{
			var param:Object = GetParam();
			param.id = id;
			param.name = name;
			param.unit = unit;
			param.typeId = typeId;
			param.storewz = storewz;
			param.storeml = storeml;
			param.storegl = storegl;
			param.supplier = supplier;
			param.misc = misc;
			param.operation = "UPDATEWARE";
			SendHttpService("data/operation.php?random=" + Math.random(),param,UpdateWareHandler);
		}
		internal function UpdateWareHandler(responseXml:XML):void
		{
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
			}
			else
			{
				theModel.dispatchEvent( new Event( IEvent.UPDATEWAREOK ));
			}
		}
		public function UpdateWareType( evt:Event):void
		{
			for( var i:int = 0; i < theModel.wareList.length; i ++ )
			{
				for( var j:int = 0; j < theModel.typeList.length; j ++ )
				{
					if( theModel.typeList[j].id == theModel.wareList[i].type )
					{
						theModel.wareList[i].typeName =  theModel.typeList[j].name;
						break;
					}
				}
			}
			
		}
		public function SubmitTicket( branch:String, branchCode:String, total:String, realPay:String, ticketDate:String, misc:String = "", clientId:int = 0):void
		{
			var sort:Sort= new Sort();
            sort.fields = [new SortField("id", true)];
            theModel.wareList.sort = sort;
			var cursor:IViewCursor = theModel.wareList.createCursor();
			// 移除过滤条件, 在整个表中查找.
			theModel.wareList.filterFunction = null;
			theModel.wareList.refresh();
			var param:Object = GetParam();
			param.id = "";
			param.store = "";	
			param.wareId = "";
			param.wareName = "";
			param.amount = "";
			param.unitPrice = "";
			param.totalAmount = ""; 
			param.typeId = "";
			// 多项结果的分割符号.
			var splitString:String = "|";
			for( var i:int = 0; i < theModel.ticketWareList.length; i ++ )
			{
				if( i == theModel.ticketWareList.length - 1 )
				{
					splitString = "";
				}
				trace( theModel.ticketWareList[i].id);
				var isFound:Boolean = cursor.findFirst({id:theModel.ticketWareList[i].id});
				// 没找到当前货品, 弹出警告后更新回数据
				if( !isFound )
				{
					Alert.show( "数据错误" );
					GetWareList(null);
					return;
				}
				var inStore:int = 0;
				// 获取库存
				switch (branch)
				{
					case theModel.shoreList[1].label:
						inStore = Number( cursor.current.remainwz );
						break;
					case theModel.shoreList[2].label:
						inStore = Number( cursor.current.remainml );
						break;
					case theModel.shoreList[3].label:
						inStore = Number( cursor.current.remaingl );
						break;
				}
				// 库存不足, 警告后更新回数据
				if( inStore < Number( theModel.ticketWareList[i].wareNumber) )
				{
					Alert.show( branch + "的" + cursor.current.name + "存货不足, 仅为" + inStore.toString() + cursor.current.unit );
					GetWareList(null);
					return;
				}
				// 计算所剩库存
				else
				{
					switch (branch)
					{
						case theModel.shoreList[1].label:
							cursor.current.remainwz = (Number(cursor.current.remainwz) - Number( theModel.ticketWareList[i].wareNumber)).toString();
							param.store +=cursor.current.remainwz+splitString;
							break; 
						case theModel.shoreList[2].label:
							cursor.current.remainml = (Number(cursor.current.remainml) - Number( theModel.ticketWareList[i].wareNumber)).toString();
							param.store +=cursor.current.remainml+splitString;
							break;
						case theModel.shoreList[3].label:
							cursor.current.remaingl = (Number(cursor.current.remaingl) - Number( theModel.ticketWareList[i].wareNumber)).toString();
							param.store +=cursor.current.remaingl+splitString;
							break;
					}
				}
				param.wareId += cursor.current.id + splitString;
				param.wareName += cursor.current.name + splitString;
				param.amount += theModel.ticketWareList[i].wareNumber + splitString;
				param.unitPrice += theModel.ticketWareList[i].price + splitString;
				param.totalAmount +=theModel.ticketWareList[i].wareAmount + splitString; 
				param.typeId += theModel.ticketWareList[i].typeId + splitString;
				var curWareListIndex:int = theModel.wareList.getItemIndex({id:theModel.ticketWareList[i].id});
			}
			
			param.shouldPay = total;
			param.realPay = realPay;
			param.branch = branch;
			param.branchCode = branchCode;
			param.ticketDate = ticketDate;
			param.misc = misc;
			param.clientId = clientId;
			param.operation = "ADDTICKET";
			SendHttpService( "data/operation.php?random=" + Math.random(), param,SubmitTicketHandler ); 
		}
		internal function SubmitTicketHandler( responseXml:XML ):void
		{
			if( responseXml.result == "true" )
				theModel.dispatchEvent( new Event( IEvent.INSERTTICKET ) );
		}
		public function ShowTicketDetails( ticketId:String ):void
		{
			theModel.ticketDetails.removeAll();
			var param:Object = GetParam();
			param.ticketId = ticketId;
			param.operation = "GETTICKETDETAILS";
			SendHttpService( "data/operation.php?random=" + Math.random(), param,ShowTicketListDetailsHandler );
		}
		internal function ShowTicketListDetailsHandler( responseXml:XML ):void
		{
			theModel.ticketDetails.removeAll();
			if( responseXml.result == "false" )
			{
				theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
				return;
			}
			var items:ArrayCollection = new ArrayCollection();
			for( var i:String in responseXml.row )
			{
				//trace(node.title);				
				var obj:Object = new Object();
				var node:XML = responseXml.row[i];
				obj.wareId = node.WAREID;
				obj.wareName = node.WARENAME;
				obj.unitPrice = node.UNITPRICE;
				obj.amount = node.AMOUNT;
				obj.value = node.VALUE;
				obj.ticketId = node.TICKETID;
				obj.misc = node.MISC;
				theModel.ticketDetails.addItem( obj );
			}
		}
		public function DeteleTicket( ticketId:String ):void
		{
			// 清空当前选中的单的详细信息
			theModel.ticketDetails.removeAll();
			var param:Object = GetParam();
			param.ticketId = ticketId;
			param.operation = "DELETETICKET";
			SendHttpService( "data/operation.php?random=" + Math.random(), param,function( responseXml:XML ):void
							{
								if( responseXml.result == "false" )
								{
									theModel.dispatchEvent( new Event( IEvent.OPERATIONFAILED));
									return;
								}
								Alert.show( "单号为:"+ticketId+"的单已删除" );
								GetTicketList(null);
							} );
		}
		public function GetTraceList( evt:Event, startDate:String="", endDate:String="" ):void
		{
			var param:Object = GetParam();
			param.startDate = startDate;
			param.endDate = endDate;
			param.operation = "GETTRACELIST";
			SendHttpService("data/operation.php?random=" + Math.random(),param,GetTraceListHandler);
		}
		internal function GetTraceListHandler( responseXml:XML ):void
		{
			theModel.traceList.removeAll();
			for( var i:String in responseXml.row )
			{
				var obj:Object = new Object();
				var node:XML = responseXml.row[i];
				obj.id = node.ID;
				obj.userId = node.USERID;
				obj.userName = node.USER;
				obj.operation= node.OPERATION;
				obj.date = node.DATE;
				obj.sqlString = node.SQLSTRING;
				theModel.traceList.addItem( obj );
			}
			theModel.traceList.refresh();
		}
	}
}